package l2ft.gameserver.model.entity.events.fightclubmanager;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javolution.util.FastMap;
import l2ft.gameserver.model.Party;
import l2ft.gameserver.model.Player;
import l2ft.gameserver.model.entity.events.fightclubmanager.FightClubAchievements.FightClubAchievement;
import l2ft.gameserver.model.entity.events.impl.AbstractFightClub;

public class FightClubPlayer implements Serializable
{
	private Player _player;
	private FightClubTeam _team;
	private Party _myParty = null;
	
	private int _score;
	private int _playerKills;
	private int _petKills;
	private Map<String, Integer> _otherCreaturesScores = new FastMap<>();
	private int _deaths;
	private boolean _invisible = false;
	private boolean _isShowRank = false;
	private boolean _isShowTutorial = false;
	private int _secondsSpentOnEvent = 0;
	private int _secondsOutsideZone = 0;

	//Afk
	private boolean _afk = false;
	private long _afkStartTime = 0;
	private int _totalAfkSeconds = 0;
	
	private FightClubAchievementProgress _achievementProgress;
	private List<FightClubAchievement> _completedAchievements = new ArrayList<>();
	private List<FightClubAchievement> _uncompletedAchievements = new ArrayList<>();
	
	public FightClubPlayer(Player player)
	{
		_player = player;
	}
	
	public void setPlayer(Player player)
	{
		_player = player;
	}
	
	public Player getPlayer()
	{
		return _player;
	}
	
	public void setTeam(FightClubTeam team)
	{
		_team = team;
	}
	
	public FightClubTeam getTeam()
	{
		return _team;
	}
	
	public Party getParty()
	{
		return _myParty;
	}
	
	public void setParty(Party party)
	{
		_myParty = party;
	}
	
	public AbstractFightClub getEvent()
	{
		return getPlayer().getFightClubEvent();
	}
	
	/*
	 * Points
	 */
	public void increaseScore(int byHowMany)
	{
		_score += byHowMany;
	}
	
	public void decreaseScore(int byHowMany)
	{
		_score -= byHowMany;
	}
	
	public void setScore(int value)
	{
		_score = value;
	}
	
	public int getScore()
	{
		return _score;
	}

	/*
	 * Kills
	 */
	public void increaseKills(boolean player1Pet0)
	{
		if(player1Pet0)
			_playerKills ++;
		else
			_petKills ++;
	}
	
	public void setKills(int value, boolean player1Pet0)
	{
		if(player1Pet0)
			_playerKills = value;
		else
			_petKills = value;
	}
	
	public int getKills(boolean player1Pet0)
	{
		if(player1Pet0)
			return _playerKills;
		else
			return _petKills;
	}
	
	/*
	 * Other Creatures kills
	 */
	
	/**
	 * Increasing it by 1
	 */
	public void increaseEventSpecificScore(String scoreKey)
	{
		if(!_otherCreaturesScores.containsKey(scoreKey))
			_otherCreaturesScores.put(scoreKey, 0);
		
		int value = _otherCreaturesScores.get(scoreKey);
		
		_otherCreaturesScores.put(scoreKey, value + 1);
	}
	
	public void setEventSpecificScore(String scoreKey, int value)
	{
		_otherCreaturesScores.put(scoreKey, value);
	}
	
	public int getEventSpecificScore(String scoreKey)
	{
		if(!_otherCreaturesScores.containsKey(scoreKey))
			return 0;
		return _otherCreaturesScores.get(scoreKey);
	}

	/*
	 * Deaths
	 */
	public void increaseDeaths()
	{
		_deaths ++;
	}
	
	public void setDeaths(int value)
	{
		_deaths = value;
	}
	
	public int getDeaths()
	{
		return _deaths;
	}

	/*
	 * Invisible
	 */
	public void setInvisible(boolean val)
	{
		_invisible = val;
	}
	
	public boolean isInvisible()
	{
		return _invisible;
	}

	/*
	 * Afk
	 */
	public void setAfk(boolean val)
	{
		_afk = val;
	}
	
	public boolean isAfk()
	{
		return _afk;
	}
	
	public void setAfkStartTime(long startTime)
	{
		_afkStartTime = startTime;
	}
	
	public long getAfkStartTime()
	{
		return _afkStartTime;
	}
	
	public void addTotalAfkSeconds(int secsAfk)
	{
		_totalAfkSeconds += secsAfk;
	}
	
	public int getTotalAfkSeconds()
	{
		return _totalAfkSeconds;
	}
	
	/*
	 * Showing Rank
	 */
	public void setShowRank(boolean b)
	{
		_isShowRank = b;
	}
	
	public boolean isShowRank()
	{
		return _isShowRank;
	}
	
	/*
	 * Show Tutorial
	 */
	public void setShowTutorial(boolean b)
	{
		_isShowTutorial = b;
	}
	
	public boolean isShowTutorial()
	{
		return _isShowTutorial;
	}
	
	/*
	 * Time Spent on event
	 */
	
	public void incSecondsSpentOnEvent(int by)
	{
		_secondsSpentOnEvent += by;
	}
	
	public int getSecondsSpentOnEvent()
	{
		return _secondsSpentOnEvent;
	}
	
	public void increaseSecondsOutsideZone()
	{
		_secondsOutsideZone++;
	}
	
	public int getSecondsOutsideZone()
	{
		return _secondsOutsideZone;
	}
	
	public void clearSecondsOutsideZone()
	{
		_secondsOutsideZone = 0;
	}

	/*
	 * 
	 * Achievements
	 * 
	 */
	
	public void setCurrentAchievement(FightClubAchievement achievement, Object target, Object action)
	{
		_achievementProgress = new FightClubAchievementProgress(achievement, target, action);
	}
	
	public FightClubAchievementProgress getAchProgress()
	{
		return _achievementProgress;
	}
	
	public FightClubAchievement getAchievement()
	{
		return getAchProgress().getAchievement();
	}
	
	public int getAchievementReward()
	{
		return getAchProgress().getReward();
	}
	
	public Object getTarget()
	{
		return getAchProgress().getTarget();
	}
	
	public Object getAchievementAction()
	{
		return getAchProgress().getAction();
	}
	
	public int getAchievementMaxProgress()
	{
		return getAchProgress().getMaxProgress();
	}
	
	public int getAchievementCurrentProgress()
	{
		return getAchProgress().getCurrentProgress();
	}
	
	public long getAchievementStartTime()
	{
		return getAchProgress()._startTime;
	}
	
	public List<FightClubAchievement> getCompletedAchievements()
	{
		return _completedAchievements;
	}
	
	/**
	 * @return time in seconds
	 */
	public int getAchievementTimeOver()
	{
		return getAchProgress().getSecondsLeft();
	}
	
	public void setAchievementTimeOver(int seconds)
	{
		getAchProgress()._secondsLeft = seconds;
	}
	
	/**
	 * @return is Achievement Completed
	 */
	public boolean setAchievementProgress(int progress)
	{
		getAchProgress()._currentProgress = progress;
		if(progress >= getAchProgress()._maxProgress)
			return true;
		return false;
	}
	
	/**
	 * @return is Achievement Completed
	 */
	public boolean increaseAchievementProgress(int addToProgress)
	{
		getAchProgress()._currentProgress += addToProgress;
		if(getAchProgress().getCurrentProgress() >= getAchProgress()._maxProgress)
			return true;
		return false;
	}

	public void breakProgress()
	{
		getAchProgress()._currentProgress = 0;
	}

	public void achievementFailed()
	{
		_uncompletedAchievements.add(getAchievement());
		_achievementProgress = null;
	}
	
	public void completeAchievement()
	{
		_completedAchievements.add(getAchievement());
		_achievementProgress = null;
	}
	
	public boolean wasAchievementTaken(FightClubAchievement ach)
	{
		return _completedAchievements.contains(ach) || _uncompletedAchievements.contains(ach);
	}
	
	/*
	 * Healing achievement
	 */
	private List<Player> _healedPlayers = new ArrayList<>();
	
	public List<Player> getHealed()
	{
		return _healedPlayers;
	}
	
	public class FightClubAchievementProgress
	{
		private final FightClubAchievement _achievement;
		private final Object _target;
		private final Object _action;
		private final int _reward;
		private int _currentProgress;
		private final int _maxProgress;
		private long _startTime;
		private int _secondsLeft;
		
		public FightClubAchievementProgress(FightClubAchievement achievement, Object target, Object action)
		{
			_achievement = achievement;
			_target = target;
			_action = action;
			_maxProgress = FightClubAchievements.getInstance().getMaxProgress(_achievement, _player.getFightClubEvent());
			_secondsLeft = FightClubAchievements.getInstance().getMaxTime(_achievement, _player.getFightClubEvent());
			_reward = FightClubAchievements.getInstance().getReward(_achievement, _player.getFightClubEvent());
			_startTime = System.currentTimeMillis();
		}
		
		public FightClubAchievement getAchievement()
		{
			return _achievement;
		}
		
		public Object getTarget()
		{
			return _target;
		}
		
		public Object getAction()
		{
			return _action;
		}
		
		public int getReward()
		{
			return _reward;
		}
		
		public int getCurrentProgress()
		{
			return _currentProgress;
		}
		
		public int getMaxProgress()
		{
			return _maxProgress;
		}
		
		public int getSecondsLeft()
		{
			return _secondsLeft;
		}
	}
}
